<template>
  <a-upload
    :file-list="fileList"
    :multiple="multiple"
    :accept="accept"
    list-type="picture-card"
    :before-upload="beforeUpload"
    :show-upload-list="true"
    @remove="handleRemove"
    @preview="handlePreview"
  >
    <div v-if="!multiple && fileList.length === 1"></div>
    <div v-else class="flex flex-col items-center justify-center">
      <upload-outlined />
      <span class="mt-1 text-xs text-gray-500">{{ tips }}</span>
    </div>
  </a-upload>

  <!-- 图片预览弹窗 -->
  <a-modal v-model:visible="previewVisible" :footer="null" title="预览" width="70%">
    <template v-if="isImage(previewUrl)">
      <img :src="previewUrl" alt="预览" style="width: 100%" />
    </template>
    <template v-else>
      <p class="text-center text-gray-500 mt-5">
        当前文件为非图片类型：
        <a :href="previewUrl" target="_blank" class="text-blue-500">点击下载查看</a>
      </p>
    </template>
  </a-modal>
</template>

<script setup lang="ts">
import { ref, watch, unref } from 'vue'
import { message } from 'ant-design-vue'
import { UploadOutlined } from '@ant-design/icons-vue'
import { useVModel } from '@vueuse/core'
import orderupFile from '@/services/account-management/orderupFile' // 上传接口
import { getUUid } from '@/utils'

interface Props {
  modelValue?: string | string[]
  multiple?: boolean
  accept?: string
  tips?: string
  previewMode?: boolean
}

const props = withDefaults(defineProps<Props>(), {
  multiple: false,
  previewMode: false,
  accept: '.png,.jpg,.jpeg,.xlsx,.xls,.pdf,.doc,.docx',
  tips: '点击上传'
})

const emit = defineEmits(['update:modelValue', 'change'])
const model = useVModel(props, 'modelValue', emit)

const fileList = ref<any[]>([])
const previewVisible = ref(false)
const previewUrl = ref('')

const [, orderupFileFn] = orderupFile()

const maxCount = props.multiple ? 15 : 1

const beforeUpload = (file: File) => {
  if (props.previewMode) {
    message.warning('预览模式下禁止操作')
    return false
  }

  if (fileList.value.length >= maxCount) {
    message.warning(`最多只能上传 ${maxCount} 个文件`)
    return false
  }

  const maxSizeMB = 10
  const isLtMax = file.size / 1024 / 1024 < maxSizeMB
  if (!isLtMax) {
    message.error(`文件大小不能超过 ${maxSizeMB}MB`)
    return false
  }

  uploadFile(file)
  return false
}

/**
 * 上传单个文件
 */
const uploadFile = async (file: File) => {
  const formData = new FormData()
  formData.append('file', file)

  message.loading('上传中')

  const [err, res] = await orderupFileFn(formData)
  if (!err && res?.data?.data) {
    const url = res.data.data
    const type = isImage(file.name)

    const newFile = {
      uid: getUUid(),
      name: file.name,
      status: 'done',
      url,
      thumbUrl: type ? url : undefined,
      isImage: type
    }

    fileList.value.push(newFile)

    model.value = props.multiple ? fileList.value.map((f) => f.url) : url

    message.success('上传成功')
  } else {
    message.error('上传失败')
  }
}

/**
 * 删除文件
 */
const handleRemove = (file: any) => {
  if (props.previewMode) {
    message.warning('预览模式下禁止操作')
    return false
  }
  fileList.value = fileList.value.filter((f) => f.uid !== file.uid)
  model.value = props.multiple ? fileList.value.map((f) => f.url) : ''
}

/**
 * 预览文件
 */
const handlePreview = (file: any) => {
  if (file.isImage) {
    previewUrl.value = file.url
    previewVisible.value = true
  } else {
    previewUrl.value = file.url
    previewVisible.value = true
  }
}

/**
 * 判断文件是否为图片
 * @param fileOrUrl File 对象或文件 URL 字符串
 * @returns boolean
 */
const isImage = (fileOrUrl: File | string) => {
  let name = ''
  if (typeof fileOrUrl === 'string') {
    name = fileOrUrl
  } else if (fileOrUrl instanceof File) {
    name = fileOrUrl.name
  }
  return /\.(png|jpe?g|gif|bmp|webp)$/i.test(name)
}
watch(
  () => props.modelValue,
  (val) => {
    if (!val) {
      fileList.value = []
      return
    }

    if (Array.isArray(val)) {
      fileList.value = val.map((url) => ({
        uid: getUUid(),
        name: url.split('/').pop(), // 提取文件名
        status: 'done',
        url,
        isImage: isImage(url),
        thumbUrl: isImage(url) ? url : undefined
      }))
    } else if (typeof val === 'string') {
      // 如果是单个字符串
      fileList.value = [
        {
          uid: getUUid(),
          name: val.split('/').pop(),
          status: 'done',
          url: val,
          isImage: isImage(val),
          thumbUrl: isImage(val) ? val : undefined
        }
      ]
    }
  },
  { immediate: true }
)
</script>
